import importlib
import inspect
import pkgutil

from axiom_boot.conf.manager import settings
from axiom_boot.di import service, order, conditional_on_setting, autowired
from axiom_boot.di.interfaces import ApplicationProcessor
from axiom_boot.di.application import AxiomApplication
from axiom_boot.logging.setup import get_logger
from axiom_boot.task.arq_manager import ArqManager

logger = get_logger(__name__)


@order(150)
@service()
@conditional_on_setting(key="run_mode", expected_value="worker")
@conditional_on_setting(key="task__enabled")
class TaskProcessor(ApplicationProcessor):
    """
    负责在 Worker 模式启动时，扫描并注册所有 @task 装饰的任务。
    """
    
    def __init__(self, arq_manager: ArqManager = autowired()):
        self.arq_manager = arq_manager

    async def process(self, app: AxiomApplication):
        logger.info("TaskProcessor: 开始扫描任务...")
        scan_packages = settings.task.scan_packages
        if not scan_packages:
            logger.warning("配置文件中 'task.scan_packages' 未设置，无法扫描任务。")
            return

        for package_name in scan_packages:
            try:
                package = importlib.import_module(package_name)
                logger.debug(f"正在扫描包: {package_name}")

                # 遍历包内的所有模块
                for _, modname, _ in pkgutil.walk_packages(package.__path__, package.__name__ + '.'):
                    try:
                        module = importlib.import_module(modname)
                        # 遍历模块内的所有成员
                        for name, obj in inspect.getmembers(module):
                            if inspect.isfunction(obj) and getattr(obj, '_is_axiom_task', False):
                                logger.info(f"发现任务: '{obj.__name__}' 位于模块 '{modname}'")
                                
                                # [关键修复] 直接将函数对象添加到列表中
                                # arq 会自动从函数对象的 'arq_task_settings' 属性中读取配置
                                if obj not in self.arq_manager.task_functions:
                                    self.arq_manager.task_functions.append(obj)

                    except Exception as e:
                        logger.error(f"扫描模块 '{modname}' 时发生错误: {e}")

            except ImportError:
                logger.error(f"无法导入指定的任务扫描包: {package_name}")
        
        logger.info(f"任务扫描完成，共发现 {len(self.arq_manager.task_functions)} 个任务。")
